package com.data.hijack.context;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author husq
 */
public final class HolderContext<T> extends InheritableThreadLocal<Map<String, Object>> {
    private static final HolderContext<Map<String, Object>> CONTEXT = new HolderContext<Map<String, Object>>();

    private HolderContext() {
        // no
    }

    public static HolderContext getInstance() {
        return instance;
    }

    /**
    * Retrieve the values from the CONTEXT
    */
    public static Map<String, Object> getValue() {
        return CONTEXT.get();
    }

    /**
     * Get value
     * 
     * @param key
     *            Obtain values from the mapping table through the key
     * @return
     */
    public static Object get(String key) {
        return CONTEXT.get().get(key);
    }

    /**
     * Get value.
     * 
     * <p>
     * <b>Not recommended for use.</b>
     * </p>
     * 
     * @param key
     *            Obtain values from the mapping table through the key
     * @param print
     *            Printing contextual content
     * @return
     */
    public static Object get(String key, boolean print) {
        if (print) {
            System.out.println(CONTEXT.get());
        }

        return get(key);
    }

    /**
     * Put value
     *
     * @param key
     *            The key in the mapping table
     * @param value
     *            Value in the mapping table
     */
    public HolderContext put(String key, Object value) {
        putOnlyPair(key, value);
        return this;
    }

    /**
     * Put value
     *
     * @param key
     *            The key in the mapping table
     * @param value
     *            Value in the mapping table
     */
    public static void putOnlyPair(String key, Object value) {
        CONTEXT.get().put(key, value);
    }

    /**
     * Remove objects from the mapping table
     *
     * @param key
     *            The key in the mapping table
     */
    public HolderContext remove(String key) {
        removeOnlyOne(key);
        return this;
    }

    /**
     * Remove objects from the mapping table
     *
     * @param key
     *            The key in the mapping table
     */
    public static void removeOnlyOne(String key) {
        CONTEXT.get().remove(key);
    }

    /**
     * Remove all objects from the mapping table
     */
    public static void removeAll() {
        CONTEXT.get().clear();
    }

    /**
     * Clear the Context
     */
    public static void expunge() {
        CONTEXT.remove();
    }

     /**
     * In the thread pool, the value of the parent thread is passed to the child thread
     * 
     * @param map
     */
    public static void transmitChild(Map<String, Object> map) {
        if (map == null || map.size() == 0) {
            return;
        }

        Set<Map.Entry<String, Object>> set = map.entrySet();
        Iterator<Map.Entry<String, Object>> itera = set.iterator();
        while (itera.hasNext()) {
            Map.Entry<String, Object> me = itera.next();
            ContextHolder.putOnlyPair(me.getKey(), me.getValue());
        }
    }

    @Override
    protected final Map<String, Object> initialValue() {
        return new WeakHashMap<String, Object>(16) {
            @Override
            public Object put(String key, Object value) {
                return super.put(key, value);
            }
        };
    }
}